const moment = require('moment');
// const { rest } = require('@directus/sdk');
const DirectusClient = require('../config/directus');
const logger = require('../utils/logger');
const {getAddress} = require("../address");

class OrderGenerator {
  constructor() {
    this.directusClient = new DirectusClient();
    this.products = [];
    this.settings = []
  }

  // 初始化数据
  async initialize() {
    try {
      this.products = await this.directusClient.getProducts();
      this.settings = await this.directusClient.getOrderSettings();

      // 系统运行开始时间
      this.systemStartMoment = moment();
      // 订单开始时间
      this.orderStartMoment = this.settings.orderStartDate ? moment(this.settings.orderStartDate) : moment();

      logger.info(`已加载 ${this.products.length} 个商品和 ${this.settings.length} 个配置项，orderStartDate: ${this.orderStartMoment.format('YYYY-MM-DD HH:mm:ss')}`);
    } catch (error) {
      logger.error('初始化订单生成器失败:', error);
      throw error;
    }
  }

  // 根据分布模式计算当前小时应该生成的订单数量
  calculateHourlyOrderCount(setting) {
    const currentHour = moment().hour();

    // 统一使用 snake_case 字段命名
    const distributionPattern = setting.distribution_pattern || 'uniform';
    const peakHours = setting.peak_hours || [];
    const peakMultiplier = setting.peak_multiplier || 2;
    const orderCountPerHour = setting.order_count_per_hour || [];

    // 目标金额
    const targetAmount = setting.target_amount || 10000;

    switch (distributionPattern) {
      case 'uniform':
        // 均匀分布：平均分配到每小时
        return Math.floor(targetAmount / 24);

      case 'peak':
        // 高峰时段分布
        if (peakHours.includes(currentHour)) {
          // 高峰时段使用倍数
          return Math.floor(targetAmount / 24) * peakMultiplier;
        } else {
          // 非高峰时段使用普通数量
          return Math.floor(targetAmount / 24);
        }

      case 'custom':
        // 自定义分布：根据 orderCountPerHour 配置
        const hourConfig = orderCountPerHour.find(config => config.hour === currentHour);
        return hourConfig ? hourConfig.count : 0;

      default:
        return Math.floor(targetAmount / 24);
    }
  }

  today() {
    const d = new Date()
    const year = d.getFullYear()
    const month = d.getMonth() + 1
    const day = d.getDate()
    const today = `${year}-${month}-${day}`
    return today
  }

  // 获取当前活跃的配置
  getActiveSettings() {
    const today = this.today()
    return this.settings.filter(setting => {
      // 检查日期范围
      const startDate = new Date(`${today} ${setting.startTime}`).getTime();
      const endDate = new Date(`${today} ${setting.endTime}`).getTime();
      const todayDate = new Date().getTime();

      // 检查今天是否在配置的日期范围内
      if (todayDate < startDate || todayDate >= endDate) {
        return false;
      }

      // 检查时间范围
      console.log('startTime', setting.startTime)
      console.log('endTime', setting.endTime)
      return true;
    });
  }

  // 执行订单生成
  async generateOrders() {
    try {
      await this.initialize();

      const activeSettings = this.getActiveSettings();

      if (activeSettings.length === 0) {
        logger.info('当前时间没有活跃的订单生成配置');
        return;
      }

      for (const setting of activeSettings) {
        const orderNum = Math.ceil(Math.random() * setting.maxOrderNum)
        logger.info(`开始为配置 "${setting.name}" 生成 ${orderNum} 个订单`);

        // const ordersData = this.generateOrdersData(setting);
        const ordersData = generateOrdersForMinute(setting, orderNum, this.products, this.systemStartMoment, this.orderStartMoment)

        if (ordersData.length > 0) {
          const createdOrders = await this.directusClient.createOrders(ordersData);

          const totalAmount = ordersData.reduce((sum, order) => sum + order.money, 0);

          logger.info(`成功生成 ${createdOrders.length} 个订单，总金额: ${totalAmount}`);

          // 更新配置的最后执行时间
          await this.updateSettingLastRun(setting.id);
        } else {
          logger.warn(`配置 "${setting.name}" 没有生成任何订单`);
        }
      }
    } catch (error) {
      logger.error('生成订单过程中发生错误:', error);
      throw error;
    }
  }

  // 更新配置的最后执行时间
  async updateSettingLastRun(settingId) {
    // try {
    //   await this.directusClient.client.request(
    //     rest().updateItem('order_settings', settingId, {
    //       last_run_at: moment().toISOString()
    //     })
    //   );
    // } catch (error) {
    //   logger.error('更新配置最后执行时间失败:', error);
    // }
  }
}

function randomInRange([min, max]) {
  return Math.floor(Math.random() * (max - min + 1)) + min
}

function getWeight(strategy, progress) {
  switch (strategy) {
    case 'uniform':
      return 1
    case 'normal':
      return Math.exp(-Math.pow((progress - 0.5) * 4, 2))
    case 'eveningPeak':
      return Math.pow(progress, 3) + 0.3
    default:
      return 1
  }
}

function generateOrdersForMinute(rule, orderNum, productsAll, systemStartMoment, orderStartMoment) {
  const orders = []

  const diff = moment().diff(systemStartMoment)

  for (let i = 0; i < orderNum; i++) {
    // 随机选择商品
    // const products = shuffleArray(productsAll).slice(0, randomInRange([1, 5]));
    const products = [
      productsAll[Math.floor(Math.random() * productsAll.length)]
    ]
    const product = products[0]
    const price = product.price || 0
    const num = Math.ceil(Math.random() * rule.maxGoodNum)
    const buyNum = [1,1,1,1,1,1,1,num,num,num][Math.floor(Math.random() * 10)]
    const money = buyNum * price

    const randomMs = Math.floor(Math.random() * 60 * 1000)
    const order_create = orderStartMoment.clone().add(diff, 'ms').add(randomMs, 'ms').toISOString()

    const orderData = {
      order_id: generateOrderNumber(),
      // 2, 3, 4
      order_status: [1,1,1,1,1,1,1,1, 5, 6, 7][Math.floor(Math.random() * 12)],
      money: parseFloat(money),
      order_goods: [
        ...products.map(product => ({goods_id: product.id}))
      ],
      num: buyNum,
      // 随机生成姓名
      buy_user: generateRandomName(),
      order_sku: product.sku?.split('\n')?.[Math.floor(Math.random() * product.sku.split('\n').length)] ?? product.sku,
      order_create,
      order_created: new Date(order_create),
      buy_address: getAddress(),
      buy_mobile: generateNonZeroMaskedPhoneNumber()
    };
    orders.push(orderData);
  }

  return orders
}

/**
 * 随机生成一个11位、以1开头、且后续数字不含0的手机号码，并隐藏中间四位。
 * 格式示例：136****1234
 * @returns {string} 隐藏中间四位的手机号码字符串
 */
function generateNonZeroMaskedPhoneNumber() {
  let phoneNumber = '1'; // 手机号固定以 '1' 开头

  // 随机生成后续10位数字 (1-9)
  for (let i = 0; i < 10; i++) {
    // Math.random() * 9 生成 0.00... 到 8.99...
    // Math.floor() 取整得到 0 到 8
    // + 1 得到 1 到 9 之间的随机整数
    const digit = Math.floor(Math.random() * 9) + 1;
    phoneNumber += digit.toString();
  }

  // 完整的手机号码：例如 13697521849

  // 提取需要替换的部分索引：
  // 前3位 (index 0, 1, 2)
  const prefix3 = phoneNumber.substring(0, 3);

  // 后4位 (index 7, 8, 9, 10)
  // 完整的11位号码，索引从 0 到 10
  const suffix4 = phoneNumber.substring(7);

  // 替换中间四位为 ****
  const maskedNumber = prefix3 + '****' + suffix4;

  // console.log(`Full Number: ${phoneNumber}`); // 调试时可查看完整号码

  return maskedNumber;
}

// 数组洗牌算法
function shuffleArray(array) {
  const shuffled = [...array];
  for (let i = shuffled.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
  }
  return shuffled;
}

// 生成随机姓名
function generateRandomName() {
  const firstNames = '尹姚邵湛汪祁毛禹狄米贝明臧计伏成戴谈宋茅庞熊纪舒屈项祝董梁杜阮蓝闵席季麻强贾路娄危江童颜郭梅盛林刁钟徐邱骆高夏蔡田樊胡凌霍虞万支柯昝管卢莫经房裘缪干解应宗丁宣贲邓郁单杭洪包诸左石崔吉钮龚程嵇邢滑裴陆荣翁荀羊於惠甄曲家封芮羿储靳汲邴糜松井段富巫乌焦巴弓牧隗山谷车侯宓蓬全郗班仰秋仲伊宫宁仇栾暴甘钭历戎祖武符刘景詹束龙叶幸司韶郜黎蓟溥印宿白怀蒲邰从鄂索咸籍赖卓蔺屠蒙池乔阳郁胥能苍双闻莘党翟谭贡劳逄姬申扶堵冉宰郦雍郤璩桑桂濮牛寿通边扈燕冀姓浦尚农温别庄晏柴瞿阎充慕连茹习宦艾鱼容向古易慎戈廖庾终暨居衡步都耿满弘匡国文寇广禄阙东欧殳沃利蔚越夔隆师巩厍聂晁勾敖融冷訾辛阚那简饶空曾毋沙乜养鞠须丰巢关蒯相查后荆红游竺权逮盍益桓公'.split('')
  // const lastName1 = ['*', '**'][Math.floor(Math.random() * 2)]
  const lastName1 = '*'
  const lastName2 = '轩, 毅, 晨, 瀚, 霖, 杰, 宇, 泽, 铭, 俊, 睿, 昊, 浩, 辰, 旭, 柏, 峰, 辉, 伟, 诚, 静, 瑶, 欣, 悦, 薇, 雅, 涵, 琪, 琳, 萱, 怡, 蕾, 菲, 雯, 洁, 姗, 莹, 宁, 柔, 曼, 强, 军, 明, 华, 鹏, 健, 龙, 勇, 涛, 波, 翔, 阳, 天, 德, 凯, 智, 远, 乐, 康, 达, 丽, 芳, 红, 梅, 娟, 翠, 兰, 霞, 萍, 惠, 艳, 秀, 瑾, 芝, 月, 琴, 莲, 颖, 云, 燕, 博, 瑞, 琛, 烨, 钧, 奕, 桓, 钰, 煜, 尧, 舜, 启, 弘, 茂, 裕, 泰, 安, 和, 泽, 胤, 依, 凝, 冰, 雪, 婧, 诗, 语, 卿, 然, 萌, 甜, 姿, 柔, 恬, 容, 慕, 婉, 淑, 芳, 佳, 凡, 逸, 致, 高, 崇, 穆, 景, 琛, 霖, 翰, 文, 哲, 义, 忠, 信, 仁, 礼, 孝, 廉, 洁, 晶, 岚, 薇, 虹, 碧, 霄, 露, 霜, 黛, 紫, 丹, 橙, 青, 蓝, 白, 玄, 墨, 金, 银, 铜, 福, 禄, 寿, 喜, 财, 吉, 顺, 昌, 隆, 丰, 年, 庆, 祥, 瑞, 兆, 禧, 康, 宁, 泰, 平, 子, 维, 肖, 迪, 伦, 珂, 玙, 珈, 琼, 瑛, 环, 珊, 珍, 珠, 璧, 璨, 铎, 钊, 铠, 钺, 修, 广, 廷, 建, 开, 志, 悟, 思, 念, 怀, 忆, 德, 慧, 敏, 捷, 聪, 颖, 睿, 智, 谋, 歌, 舞, 乐, 典, 艺, 术, 律, 诗, 画, 绣, 锦, 帛, 纱, 罗, 绫, 绢, 丝, 棉, 麻, 纺, 江, 河, 湖, 海, 川, 溪, 泉, 淼, 潮, 浪, 涛, 涌, 汀, 沙, 洲, 岸, 岭, 岗, 岳, 峰, 枫, 松, 柏, 楠, 桐, 柳, 桃, 李, 杏, 枣, 柿, 橘, 橙, 荔, 桂, 莲, 荷, 菊, 兰, 梅, 炎, 火, 焱, 灿, 炳, 炯, 煜, 炻, 烽, 煊, 炜, 炅, 炘, 炷, 炣, 烁, 烓, 焄, 焓, 焕'.split(', ')
  const randomFirstName = firstNames[Math.floor(Math.random() * firstNames.length)]
  const randomLastName = lastName2[Math.floor(Math.random() * lastName2.length)]
  return `${randomFirstName}${lastName1}${randomLastName}`
}

// 生成订单号
function random1to6Digits() {
  const len = Math.floor(Math.random() * 6) + 1; // 1~6
  const min = Math.pow(10, len - 1);
  const max = Math.pow(10, len) - 1;
  return len === 1 ? Math.floor(Math.random() * 10) : Math.floor(Math.random() * (max - min + 1)) + min;
}
function generateOrderNumber() {
  // const prefix = process.env.DEFAULT_ORDER_PREFIX || '';
  // 订单号 16-22位随机数 + 6位随机数
  const random = Math.floor(Math.random() * 1000000000000000).toString().padStart(16, '0')
  const random1 = random1to6Digits().toString()
  return `${random}${random1}`;
}

module.exports = OrderGenerator;
